home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Blender 2.49b / blender-2.49b-windows.exe / $_4_ / .blender / scripts / animation_clean.py < prev    next >
Text File  |  2009-08-31  |  5KB  |  193 lines

  1. #!BPY
  2.  
  3. """
  4. Name: 'Clean Animation Curves'
  5. Blender: 249
  6. Group: 'Animation'
  7. Tooltip: 'Remove unused keyframes for ipo curves'
  8. """
  9.  
  10. # ***** BEGIN GPL LICENSE BLOCK *****
  11. #
  12. # Copyright (C) 2008-2009: Blender Foundation
  13. #
  14. # This program is free software; you can redistribute it and/or
  15. # modify it under the terms of the GNU General Public License
  16. # as published by the Free Software Foundation; either version 2
  17. # of the License, or (at your option) any later version.
  18. #
  19. # This program is distributed in the hope that it will be useful,
  20. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.    See the
  22. # GNU General Public License for more details.
  23. #
  24. # You should have received a copy of the GNU General Public License
  25. # along with this program; if not, write to the Free Software Foundation,
  26. # --------------------------------------------------------------------------
  27.  
  28. import bpy
  29. from Blender import IpoCurve, Draw, Window
  30.  
  31. def clean_ipos(ipos):
  32.     eul = 0.001
  33.  
  34.     def isflat(vec):
  35.         prev_y = vec[0][1]
  36.         mid_y = vec[1][1]
  37.         next_y = vec[2][1]
  38.         
  39.         # flat status for prev and next
  40.         return abs(mid_y-prev_y) < eul, abs(mid_y-next_y) < eul
  41.         
  42.         
  43.             
  44.     X=0
  45.     Y=1
  46.     PREV=0
  47.     MID=1
  48.     NEXT=2
  49.  
  50.     LEFT = 0
  51.     RIGHT = 1
  52.  
  53.     TOT = 0
  54.     TOTBEZ = 0
  55.     # for ipo in bpy.data.ipos:
  56.     for ipo in ipos:
  57.         if ipo.lib: 
  58.             continue
  59.         # print ipo
  60.         for icu in ipo:
  61.             interp = icu.interpolation
  62.             extend = icu.extend 
  63.             
  64.             bezierPoints = icu.bezierPoints
  65.             bezierVecs = [bez.vec for bez in bezierPoints]
  66.             
  67.             l = len(bezierPoints)
  68.             
  69.             TOTBEZ += l
  70.             
  71.             # our aim is to simplify this ipo as much as possible!
  72.             if interp == IpoCurve.InterpTypes.BEZIER or interp == interp == IpoCurve.InterpTypes.LINEAR:
  73.                 #print "Not yet supported"
  74.                 
  75.                 if interp == IpoCurve.InterpTypes.BEZIER:
  76.                     flats = [isflat(bez) for bez in bezierVecs]
  77.                 else:
  78.                     # A bit of a waste but fake the locations for these so they will always be flats
  79.                     # IS better then too much duplicate code.
  80.                     flats = [(True, True)] * l
  81.                     for v in bezierVecs:
  82.                         v[PREV][Y] = v[NEXT][Y] = v[MID][Y]
  83.                     
  84.                 
  85.                 # remove middle points
  86.                 if l>2:
  87.                     done_nothing = False
  88.                     
  89.                     while not done_nothing and len(bezierVecs) > 2:
  90.                         done_nothing = True
  91.                         i = l-2
  92.                     
  93.                         while i > 0:
  94.                             #print i
  95.                             #print i, len(bezierVecs)
  96.                             if flats[i]==(True,True)  and  flats[i-1][RIGHT]  and  flats[i+1][LEFT]:
  97.                             
  98.                                 if abs(bezierVecs[i][MID][Y] - bezierVecs[i-1][MID][Y]) < eul   and   abs(bezierVecs[i][MID][Y] - bezierVecs[i+1][MID][Y]) < eul:
  99.                                     done_nothing = False
  100.                                     
  101.                                     del flats[i]
  102.                                     del bezierVecs[i]
  103.                                     icu.delBezier(i)
  104.                                     TOT += 1
  105.                                     l-=1
  106.                             i-=1
  107.                 
  108.                 # remove endpoints
  109.                 if extend == IpoCurve.ExtendTypes.CONST and len(bezierVecs) > 1:
  110.                     #print l, len(bezierVecs)
  111.                     # start
  112.                     
  113.                     while l > 2 and (flats[0][RIGHT]  and  flats[1][LEFT] and (abs(bezierVecs[0][MID][Y] - bezierVecs[1][MID][Y]) < eul)):
  114.                         print "\tremoving 1 point from start of the curve"
  115.                         del flats[0]
  116.                         del bezierVecs[0]
  117.                         icu.delBezier(0)
  118.                         TOT += 1
  119.                         l-=1
  120.                     
  121.                     
  122.                     # End 
  123.                     while l > 2 and flats[-2][RIGHT]  and  flats[-1][LEFT] and (abs(bezierVecs[-2][MID][Y] - bezierVecs[-1][MID][Y]) < eul):
  124.                         print "\tremoving 1 point from end of the curve", l
  125.                         del flats[l-1]
  126.                         del bezierVecs[l-1]
  127.                         icu.delBezier(l-1)
  128.                         TOT += 1
  129.                         l-=1
  130.                         
  131.                 
  132.                         
  133.                 if l==2:
  134.                     if isflat( bezierVecs[0] )[RIGHT] and isflat( bezierVecs[1] )[LEFT] and abs(bezierVecs[0][MID][Y] - bezierVecs[1][MID][Y]) < eul:
  135.                         # remove the second point
  136.                         print "\tremoving 1 point from 2 point bez curve"
  137.                         # remove the second point
  138.                         del flats[1]
  139.                         del bezierVecs[1]
  140.                         icu.delBezier(1)
  141.                         TOT+=1
  142.                         l-=1
  143.                         
  144.                 # Change to linear for faster evaluation
  145.                 '''
  146.                 if l==1:
  147.                     print 'Linear'
  148.                     icu.interpolation = IpoCurve.InterpTypes.LINEAR
  149.                 '''
  150.                 
  151.         
  152.             
  153.             
  154.             if interp== IpoCurve.InterpTypes.CONST:
  155.                 print "Not yet supported"
  156.                 
  157.     print 'total', TOT, TOTBEZ
  158.     return TOT, TOTBEZ
  159.  
  160. def main():
  161.     ret = Draw.PupMenu('Clean Selected Objects Ipos%t|Object IPO%x1|Object Action%x2|%l|All IPOs (be careful!)%x3')
  162.     
  163.     sce = bpy.data.scenes.active
  164.     ipos = []
  165.     
  166.     if ret == 3:
  167.         ipos.extend(list(bpy.data.ipos))
  168.     else:
  169.         for ob in sce.objects.context:
  170.             if ret == 1:
  171.                 ipo = ob.ipo
  172.                 if ipo:
  173.                     ipos.append(ipo)
  174.             
  175.             elif ret == 2:
  176.                 action = ob.action
  177.                 if action:
  178.                     ipos.extend([ipo for ipo in action.getAllChannelIpos().values() if ipo])
  179.         
  180.             
  181.     
  182.     if not ipos:
  183.         Draw.PupMenu('Error%t|No ipos found')
  184.     else:
  185.         total_removed, total = clean_ipos(ipos)
  186.         Draw.PupMenu('Done!%t|Removed ' + str(total_removed) + ' of ' + str(total) + ' points')
  187.     
  188.     Window.RedrawAll()
  189.     
  190.  
  191. if __name__ == '__main__':
  192.     main()
  193.